home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / OVERLAY / OVRUMB12 / OVRUMB.PAS < prev   
Pascal/Delphi Source File  |  1994-09-15  |  8KB  |  225 lines

  1. unit OvrUMB;
  2.  
  3.   { Unit OvrUMB : Uses an upper memory block as overlay buffer         }
  4.   {                                                                    }
  5.   {   Version 1.2 (15/09/94)                                           }
  6.   {                                                                    }
  7.   {   Author : Jean-Marc Lasgouttes                                    }
  8.   {                                                                    }
  9.   {   e-mail : Jean-Marc.Lasgouttes@inria.fr                           }
  10.  
  11.  
  12. {$A+,F-,O-,S-}
  13.  
  14.  
  15. interface
  16.  
  17.   uses Overlay;
  18.  
  19.   Procedure OvrSetBufUMB(Size:longint);
  20.   {Frees the current overlay buffer (which must be before the heap),
  21.    allocates a new buffer of Size bytes in upper memory and sets the
  22.    overlay manager to use this buffer. This is only possible if the
  23.    heap is empty and no overlays are currently loaded. This procedure
  24.    must not be used if the buffer has been already reallocated
  25.    somewhere
  26.  
  27.    #OvrMovBufToUMB# is an automatic version of this procedure that generate
  28.    more efficient code.}
  29.  
  30.   Procedure OvrMovBufToUMB;
  31.   {Same procedure as #OvrSetBufUMB#, except that the size of the UMB buffer
  32.    is the biggest available upper memory block. No rellocation occurs if
  33.    the biggest block is smaller than the current overlay buffer. This is the
  34.    most convenient procedure to use.}
  35.  
  36.   Function UMB_MaxAvail:longint;
  37.   {Returns the size of the biggest available upper memory block}
  38.  
  39. implementation
  40.  
  41.   const OvrUMBSeg:word=0;      {The Segment of the overlay buffer}
  42.  
  43.   var   OldExitProc:Pointer;   {The old ExitProc (surprise!)}
  44.     SaveMemStrat,           {Temporary variables to save system state}
  45.     SaveUMBLink:word;
  46.  
  47.   Function ChangeMemStrat:boolean; assembler;
  48.   {Save the current memory allocation strategy and change it in order
  49.    to allocate upper memory}
  50.   asm
  51.     MOV   AX, 5800h               {Save memory allocation strategy}
  52.     INT   21h
  53.     MOV   SaveMemStrat, AX
  54.     MOV   AX, 5802h                    {Save UMB Link state}
  55.     INT   21h
  56.     MOV   SaveUMBLink, AX
  57.     JC    @@1                          {If this function is not recognized}
  58.                                        {  then DOS version <5 : Error}
  59.     MOV   AX, 5801h                    {Set memory allocation strategy to}
  60.     MOV   BX, 40h                      {  use only upper memory}
  61.     INT   21h
  62.     MOV   AX, 5803h                    {Add UMB to DOS memory chain}
  63.     MOV   BX, 1
  64.     INT   21h
  65.     JNC   @@2                   {Error: no UMB provider}
  66. @@1:MOV   AX, false                    {Return an error}
  67.     JMP   @@3
  68. @@2:MOV   AX, true                     {Return success}
  69. @@3:
  70.   end;
  71.  
  72.   Procedure ResetMemStrat; assembler;
  73.   {Restore the memory allocation strategy as it was before the call to
  74.    ChangeMemStrat}
  75.   asm
  76.     MOV   AX, 5801h               {Reset the memory allocation strategy}
  77.     MOV   BX, SaveMemStrat
  78.     INT   21h
  79.     MOV   AX, 5803h                   {Reset the UMB link state}
  80.     MOV   BX, SaveUMBLink
  81.     INT   21h
  82.   end;
  83.  
  84.   Procedure ReleaseUMB(UMBSeg:word); assembler;
  85.   {Releases the block corresponding to UMBSeg if UMBSeg<>0}
  86.   asm
  87.     MOV   AX, UMBSeg                   {If the segment is zero, do nothing}
  88.     CMP   AX, 0
  89.     JZ    @@1
  90.     MOV   AX, 5802h                   {Save UMB Link state}
  91.     INT   21h
  92.     MOV   SaveUMBLink, AX
  93.     MOV   AX, 5803h
  94.     MOV   BX, 0                       {Remove UMB from DOS memory chain}
  95.     INT   21h
  96.     MOV   AH, 49h                      {Free block used by UMBSeg}
  97.     MOV   ES, UMBSeg
  98.     INT   21h
  99.     MOV   AX, 5803h                    {Reset UMB link state}
  100.     MOV   BX, SaveUMBLink
  101.     INT   21h
  102. @@1:
  103.   end;
  104.  
  105.   Procedure PrimSetBufUMB(Size:word); assembler;
  106.   {The basic procedure called by OvrSetBufUMB and OvrMovBufToUMB. Size
  107.    is given in paragraphs.}
  108.   asm
  109.     XOR   AX, AX                       {Check for errors: }
  110.     CMP   AX, OvrDOSHandle             {  Is the Overlay file opened?}
  111.     JZ    @@3
  112.     CMP   AX, OvrLoadList              {  Are there some Overlays loaded?}
  113.     JNZ   @@3
  114.     MOV   AX, OvrHeapEnd               {  Is the buffer already rellocated?}
  115.     CMP   AX, WORD PTR HeapOrg+2
  116.     JNZ   @@3
  117.     CMP   AX, WORD PTR HeapPtr+2       {  Is there something in the heap?}
  118.     JNZ   @@3
  119.     MOV   AH, 48h                      {Allocate UMBSize segments of memory}
  120.     MOV   BX, Size
  121.     INT   21h
  122.     JNC   @@1
  123.     MOV   AX, ovrNoMemory              {Not enough UMB}
  124.     JMP   @@2
  125. @@1:MOV   OvrUMBSeg, AX                {Keep the segment in OvrUMBSeg}
  126.     MOV   AX, OvrHeapOrg
  127.     MOV   WORD PTR HeapOrg+2, AX       {Seg(HeapOrg):=OvrHeapOrg}
  128.     MOV   WORD PTR HeapPtr+2, AX       {Seg(HeapPtr):=OvrHeapOrg}
  129.     MOV   WORD PTR FreeList+2, AX      {Seg(FreeList):=OvrHeapOrg}
  130.     XOR   AX, AX
  131.     MOV   WORD PTR HeapOrg, AX         {Ofs(HeapOrg):=0}
  132.     MOV   WORD PTR HeapPtr, AX         {Ofs(HeapPtr):=0}
  133.     MOV   WORD PTR FreeList, AX        {Ofs(FreeList):=0}
  134.     MOV   AX, OvrUMBSeg
  135.     MOV   OvrHeapOrg, AX               {OvrHeapOrg:=OvrUMBSeg }
  136.     MOV   OvrHeapPtr, AX               {OvrHeapPtr:=OvrUMBSeg }
  137.     ADD   AX, Size
  138.     MOV   OvrHeapEnd, AX               {OvrHeapEnd:=OvrUMBSeg+Size}
  139.     MOV   AX, ovrOK                    {Success}
  140.     JMP   @@2
  141. @@3:MOV   AX, ovrError
  142. @@2:MOV   OvrResult, AX                {Put the result in OvrResult}
  143.   end;
  144.  
  145.   Function UMB_MaxAvail:longint; assembler;
  146.   asm
  147.     CALL  ChangeMemStrat               {Allow the use of upper memory}
  148.     CMP   AX, false
  149.     JZ    @@1                          {if it not possible, return 0}
  150.     MOV   AH, 48h                      {Try to allocate too much memory}
  151.     MOV   BX, 0FFFFh
  152.     INT   21h                          {BX contains the size of the biggest}
  153.     MOV   AX, BX                       {  available block}
  154.     XOR   DX, DX
  155.     SHL   AX, 1                        {Multiply by 16 and put the result}
  156.     RCL   DX, 1                        {  in DX:AX}
  157.     SHL   AX, 1
  158.     RCL   DX, 1
  159.     SHL   AX, 1
  160.     RCL   DX, 1
  161.     SHL   AX, 1
  162.     RCL   DX, 1
  163.     JMP   @@2
  164. @@1:XOR   AX, AX
  165.     XOR   DX, DX
  166. @@2:PUSH  AX
  167.     PUSH  DX
  168.     CALL  ResetMemStrat                {Reset the memory allocation strategy}
  169.     POP   DX
  170.     POP   AX
  171.   end;
  172.  
  173.   Procedure OvrSetBufUMB(Size:longint); assembler;
  174.   asm
  175.     CALL  ChangeMemStrat               {Allow the use of upper memory}
  176.     CMP   AX, false
  177.     JZ    @@1                          {If it is impossible, abort}
  178.     MOV   AX, WORD PTR Size            {Transform Size}
  179.     MOV   DX, WORD PTR Size+2          {  into a number of paragraphs}
  180.     MOV   CL, 04h
  181.     SHR   AX, CL
  182.     ROR   DX, CL
  183.     AND   DX, 0F000h
  184.     OR    AX, DX                       {  the result is in AX}
  185.     CMP   AX, OvrHeapSize              {If AX < OvrHeapSize --> Error}
  186.     JB    @@1
  187.     PUSH  AX
  188.     CALL  PrimSetBufUMB                {Actually allocate and set the buffer}
  189.     JMP   @@2
  190. @@1:MOV   AX, ovrError                 {Report an Error}
  191.     MOV   OvrResult, AX
  192. @@2:CALL  ResetMemStrat
  193.   end;
  194.  
  195.   Procedure OvrMovBufToUMB; assembler;
  196.   asm
  197.     CALL  ChangeMemStrat               {Allow the use of upper memory}
  198.     CMP   AX, false
  199.     JZ    @@1                          {If it is impossible, abort}
  200.     MOV   AH, 48h                      {Try to allocate too much memory}
  201.     MOV   BX, 0FFFFh
  202.     INT   21h                          {BX contains the size of the biggest}
  203.                                        {  available upper memory block}
  204.     MOV   AX, OvrHeapEnd               {Compute the size of the}
  205.     SUB   AX, OvrHeapOrg               {  current Overlay buffer}
  206.     CMP   AX, BX                       {Is the UMB bigger than the current buffer?}
  207.     JNB   @@1                          {If not, abort}
  208.     PUSH  BX
  209.     CALL  PrimSetBufUMB                {Actually allocate and set the buffer}
  210.     JMP   @@2
  211. @@1:MOV   OvrResult, OvrNoMemory
  212. @@2:CALL  ResetMemStrat
  213.   end;
  214.  
  215.   Procedure OvrUMBExitProc; far;
  216.   begin
  217.     ExitProc:=OldExitProc;             {Chain to the old exit handler}
  218.     ReleaseUMB(OvrUMBSeg);             {Release the overlay buffer}
  219.   end;
  220.  
  221. begin
  222.   OldExitProc:=ExitProc;
  223.   ExitProc:=@OvrUMBExitProc;           {Release the UMB on exit}
  224. end.
  225.